#pragma once
#include <iostream>
#include <sys/epoll.h>
#include "Log.hpp"
#include "Comm.hpp"

class Epoller
{
    void EpollCore(int fd, int events, int flag)
    {
        // LOG(DEBUG, "fd : %d, events : %d\n", fd, events);
        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = events;

        int n = ::epoll_ctl(_epfd, flag, fd, &ev);
        if (n < 0)
        {
            LOG(ERROR, "ctl error, fd : %d\n", fd);
        }
        else
        {
            LOG(INFO, "%d is ctl to epoll\n", fd);
        }
    }
public:
    Epoller()
    {
        _epfd = ::epoll_create(128);
        if (_epfd < 0)
        {
            LOG(FATAL, "epoll create fail\n");
            exit(1);
        }
        LOG(INFO, "epoll create success\n");
    }
    void AddEvents(int fd, uint32_t events)
    {
        EpollCore(fd, events, EPOLL_CTL_ADD);
    }
    void ModEvents(int fd, uint32_t events)
    {
        EpollCore(fd, events, EPOLL_CTL_MOD);
    }
    void DelEvents(int fd)
    {
        int n = ::epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr);
        if (n < 0)
        {
            LOG(ERROR, "DelEvents error, fd : %d\n", fd);
        }
        else
        {
            LOG(INFO, "%d is del from epoll\n", fd);
        }
    }
    int Wait(struct epoll_event *epArr, int num, int timeout)
    {
        int n = ::epoll_wait(_epfd, epArr, num, timeout);
        return n;
    }
    ~Epoller()
    {
        if (_epfd > -1)
            ::close(_epfd);
    }

private:
    int _epfd;
};